// 打包文件分析工具, 只在生产环境时使用 ==> BundleAnalyzerPlugin
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
// gzip压缩 ==> CompressionPlugin
const CompressionPlugin = require("compression-webpack-plugin");
// 代码编辑器
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const ran = require("./config/ran");
const conf = require("./config/projectConf");
const path = require("path");
const projectName = require('./config/project').name;

function resolve(dir) {
    return path.join(__dirname, dir);
}

module.exports = {
    // 部署应用包时的基本 URL
    publicPath: "./",
    // 生产打包时不输出map文件，增加打包速度, 配合 new CompressionPlugin
    productionSourceMap: false,
    // 配置关闭Eslint
    lintOnSave: false,
    devServer: {
        // 自动打开浏览器
        open: true,
        // 实时打包编译
        hot: true,
        // 表示实时刷新浏览器
        inline: true,
        // 指定打开浏览器的端口号
        port: "8080",
        // 修改代理
        // proxy: {
        //     '/gxsyyf/verify': {     
        //         target: 'http://39.108.58.158:8090',  
        //         ws: true,      
        //         secure: false, 
        //         changeOrigin: true,  
        //     }
        // }
    },
    pages: conf.pages,
    // 打包输出路径
    outputDir: conf.outputDir,
    // 静态资源文件输出路径
    assetsDir: "static",
    css: { 
        //是否将组件中的 CSS 提取至一个独立的 CSS 文件中，热重载不兼容，避免用户自己导入 CSS
        extract: false
    },
    // webpack 简单的配置方式
    configureWebpack: config => {
        if (process.env.NODE_ENV === "production") {
            config.mode = "production";
            // 使用打包分析工具
            config.plugins.push(new BundleAnalyzerPlugin());
            // 使用“terser-webpack-plugin”去除console
            config.optimization.minimizer[0].options.terserOptions = {
                compress: {
                    warnings: false, // 是否移除未使用的声明等显示警告
                    drop_console: true, // 注释console
                    drop_debugger: true,
                    pure_funcs: ["console.log"] // 移除console
                }
            };
            
        } else {
            config.mode = "development";
        }
        
        config.plugins.concat([
            // Brotli压缩配置,相对gzip压缩提高20%
            // algorithm: "brotliCompress" 需要node>10.16.0及更高版本在其zlib模块中具有对Brotli压缩的本机支持
            new CompressionPlugin({
                filename: "[path].br[query]",
                algorithm: "brotliCompress",
                test: /\.(js|css|html|svg)$/,
                compressionOptions: { level: 11 },
                threshold: 10240,
                minRatio: 0.8,
                deleteOriginalAssets: true
            }),
        ]);

        // 在打包或编译代码后执行相关函数操作
        config.plugins.push({
            apply: compiler => {
                compiler.hooks.done.tap("*", ran);
            }
        });
        

        // 覆盖vue-cli的webpack配置,返回的对象会被merge至webpack.config
        return {
            resolve: {
                extensions: [".js", ".vue", ".json"],
                alias: {
                    vue$: "vue/dist/vue.esm.js",
                    "@": resolve("src"),
                    "@assets": resolve("src/assets"),
                    "@component": resolve("src/component"),
                    "@store": resolve("src/store"),
                    "public": resolve("public/public"),
                }
            },
            output: {
                // 生成chunk文件,不使用contenthash:8,尽可能的避免前端缓存问题
                filename: "static/js/[name].[hash].js",
                chunkFilename: "static/js/[chunkhash:8].[chunkhash].js"
            }
        };
    },
    // webpack 原始配置的上层抽象，允许我们更细粒度的控制其内部配置
    chainWebpack: config => {
        /**********************************************************************************************************
         *  @description 关闭预加载模块。prefetch: 预先加载模块
         *  @reason 因为此模块,会提前获取用户未来可能会访问的内容,在首屏会把这N+个路由文件全下载。
         *  @example 我只打开了登录页面, 什么都不操作, 却把所有路由文件都加载, 浪费资源
         ***********************************************************************************************************/
            // 移除 prefetch 插件
            config.plugins.delete("prefetch-index");    
            // 移除 preload 插件
            config.plugins.delete('preload-index');

            // markdown解析
            config.module
                .rule("md")
                .test(/\.md$/)
                .use("html-loader")
                .loader("html-loader")
                .end() 
                .use("markdown-loader")
                .loader("markdown-loader")
                .options({})
                .end(); 

            // babel兼容/转码器，可以将ES6代码转为ES5代码，兼容低版本浏览器
            config.entry('index').add('babel-polyfill');

            // 代码编写解析器
            // if(projectName === 'web') {
            //     config.plugin('monaco').use(
            //         new MonacoWebpackPlugin({
            //             languages: ['typescript'],
            //             filename: 'static/js/[name].worker.js'
            //         })
            //     )
            // }
 
     }
};